// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// File:	scheduledproject.cpp
// Author: 	Kirk Larkin
// Date: 	25/09/2008
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#include "scheduledproject.h"

// Qt Includes
#include <QtDebug>

// ------------------------------------------------------------------
// Construction & Destruction
// ------------------------------------------------------------------
ScheduledProject::ScheduledProject(const QString &strProjectPath, const QTime &tmSchedule,
		QObject *pParent/* = NULL*/)
	: QObject(pParent),
	  m_strProjectPath(strProjectPath),
	  m_tmSchedule(tmSchedule),
	  m_pProjectInstance(NULL)
{
	// Setup the scheduling for this project.
	updateSchedule();
}

// ------------------------------------------------------------------
// Public Slots
// ------------------------------------------------------------------
void ScheduledProject::runProject()
{
	m_pProjectInstance = new Project(QFileInfo(m_strProjectPath).absoluteDir());

	// Signals & Slots.
	connect(m_pProjectInstance, SIGNAL(stateChanged(Project::tProjectState)), this, SLOT(onProjectStateChanged(Project::tProjectState)));

	// Launch the project itself.
	// TODO: Thomi, why do I have to provide the project-path in the constructor AND here?
	updateSchedule(QDateTime::currentDateTime());
	m_pProjectInstance->runProject(m_strProjectPath);
}

// ------------------------------------------------------------------
// Member Functions
// ------------------------------------------------------------------
const QDateTime& ScheduledProject::updateSchedule(const QDateTime &dtLastRun/* = QDateTime()*/)
{
	// If dtLastRun is not null, we store it and then use it to schedule our next run.
	// If dtLastRun is null, we use m_dtLastRun to schedule our next run.
	if(!dtLastRun.isNull())
		m_dtLastRun = dtLastRun;

	// m_dtLastRun will be invalid if the project has not yet been scheduled.
	if(m_dtLastRun.isNull())
	{
		// In which case, we schedule the project to run after the given interval
		// using the current time as a baseline.
		m_dtNextRun = QDateTime::currentDateTime();
	}
	else
	{
		// Otherwise, our baseline is the time we last ran the project.
		m_dtNextRun = m_dtLastRun;
	}

	// Then we schedule the project to run again after the given interval.
	// We are relying on a valid m_tmSchedule (see constructor).
	m_dtNextRun = m_dtNextRun.addSecs(QTime(0, 0, 0).secsTo(m_tmSchedule));
	
	// Return the next-scheduled time for the scheduler.
	return m_dtNextRun;
}

// ------------------------------------------------------------------
// Private Slots
// ------------------------------------------------------------------
void ScheduledProject::onProjectStateChanged(Project::tProjectState eProjectState)
{
	switch(eProjectState)
	{
		case Project::STATE_INITIAL:
		case Project::STATE_WAIT_COPY:
		case Project::STATE_WAIT_BROWSE:
		case Project::STATE_SCANNING:
		case Project::STATE_OUTPUT:
			break;

		case Project::STATE_DONE:
		{
			m_pProjectInstance->deleteLater();
			m_pProjectInstance = NULL;
			emit projectComplete(eProjectState);
			break;
		}
	}
}
